#ifndef AVALON_HTTPSESSIONHANDLER_HPP
#define AVALON_HTTPSESSIONHANDLER_HPP
#include "Avalon/Threading/Timer.hpp"
#include "Avalon/WebServices/HttpServer.hpp"

namespace Avalon {
namespace WebServices {

  /*! \class HttpSessionHandler
   *  \brief Creates and manages HTTP sessions.
   *  \author Kamal Mansouri <kranar@hotmail.com>
   */
  class HttpSessionHandler {
    public:

      //! The default timeout.
      static const boost::posix_time::time_duration TIMEOUT;

      //! The name of the sessionid Cookie.
      static const std::string SESSION_ID;

      //! Signals a new HttpSession was created.
      /*!
        \param session The new HttpSession.
      */
      typedef boost::signals2::signal<void (HttpSession*)> NewSessionSignal;

      //! Signals an HttpSession has expired.
      /*!
        \param session The expired HttpSession.
      */
      typedef boost::signals2::signal<void (HttpSession*)> SessionExpiredSignal;

      //! Signals an incoming HTTP request.
      /*!
        \param session The HTTP session assigned to the request.
        \param request The HTTP request.
        \param response The HTTP response.
      */
      typedef boost::signals2::signal<void (HttpSession*, HttpServerRequest*,
        HttpServerResponse*)> HttpRequestSignal;

      //! Constructs an HttpSessionHandler.
      /*!
        \param sessionFactory Used to create new HTTP sessions.
        \param timeout The length of time before a session time's out.
      */
      HttpSessionHandler(HttpSessionFactory* sessionFactory,
        boost::posix_time::time_duration timeout = TIMEOUT);

      ~HttpSessionHandler();

      //! Connects to the NewSessionSignal.
      /*!
        \param slot The slot to call when a new HttpSession is created.
        \return A connection to the NewSessionSignal.
      */
      boost::signals2::connection ConnectNewSessionSignal(
        const NewSessionSignal::slot_type& slot);

      //! Connects to the SessionExpiredSignal.
      /*!
        \param slot The slot to call when an HttpSession expires.
        \return A connection to the SessionExpiredSignal.
      */
      boost::signals2::connection ConnectSessionExpiredSignal(
        const SessionExpiredSignal::slot_type& slot);

      //! Returns a slot that's called when an HttpServer signals a request.
      /*!
        \param slot The slot to call upon the HttpServer request.
        \return A slot compatible with this HttpSessionHandler.
      */
      HttpServer::HttpRequestSignal::slot_type GetSlot(
        const HttpRequestSignal::slot_type& slot);

    private:
      boost::mutex m_mutex;
      boost::scoped_ptr<HttpSessionFactory> m_sessionFactory;
      std::map<std::string, HttpSession*> m_sessions;
      NewSessionSignal m_newSessionSignal;
      SessionExpiredSignal m_sessionExpiredSignal;

      HttpSession* CreateSession();
      void OnRequest(HttpServerRequest* request, HttpServerResponse* response,
        const HttpRequestSignal::slot_type& slot);
  };
}
}

#endif // AVALON_HTTPSESSIONHANDLER_HPP
